package com.tj.collection.controller.chatquality;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.common.api.Page;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.HttpUtil;
import com.fqgj.common.utils.StringUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jsoniter.output.JsonStream;
import com.kly.dto.UserBenefitsDto;
import com.kly.service.MemberBenefitsService;
import com.kly.user.chatterService.ChatterUserService;
import com.kly.user.dto.UserBaseDto;
import com.kly.user.dto.UserInfoDto;
import com.kly.user.dto.UserMsgListDto;
import com.kly.user.dto.chatter.Chatter;
import com.kly.user.dto.chatter.response.ChatterWorkingSetDto;
import com.kly.user.dto.report.*;
import com.kly.user.enums.UserTokenType;
import com.kly.user.service.*;
import com.tj.collection.common.Result;
import com.tj.collection.controller.BaseCompent;
import com.tj.collection.controller.chatquality.request.*;
import com.tj.collection.controller.chatquality.response.*;
import com.tj.collection.db.domain.ChatterOnlineDto;
import com.tj.collection.db.domain.RptChatterDataPreDayDto;
import com.tj.collection.db.domain.RptModelDataPreDayDto;
import com.tj.collection.db.service.QualityService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 会话质检相磁
 */
@Slf4j
@RestController
@RequestMapping("/chat/quality/control")
@Api(value = "每日质检相关接口", tags = {"每日质检相关接口"})
public class ChatQualityController extends BaseCompent {

    @Resource
    private ChatterService chatterService;
    @Resource
    private ReportQueryService reportQueryService;
    @Resource
    UserService userService;
    @Resource
    ChatterUserService chatterUserService;
    @Resource
    QualityService qualityService;
    @NacosValue(value = "${chatter.url}", autoRefreshed = true)
    private String chatterApiUrl;
    @Resource
    AuthLoginService authLoginService;
    @Resource
    UserMsgService userMsgService;
    @Resource
    MemberBenefitsService memberBenefitsService;


    @ApiOperation("chatter展示接口")
    @RequestMapping(value = "/chatter/list", method = {RequestMethod.POST})
    public Result<ChatterListRsp> cahtterList(@RequestBody ChatterListReq request) {

        final BaseCompent.AccountRole accountRole = getAccountRole();

        final Integer chattersCnt = chatterService.getChattersCnt(setupChatterListQueryParams(request, accountRole));
        if (chattersCnt == null || chattersCnt == 0) {
            return Result.ok(ChatterListRsp.builder().totalNum(0).build());
        }

        // 获取chatter列表数据
        List<Chatter> chatters = chatterService.getChatters(setupChatterListQueryParams(request, accountRole), new Page(request.getPageSize(), request.getCurrent()));
        // 获取在线率
        List<OnlineReportDto> onlineReportDtoList = getOnlineReportDtos(request, accountRole);
        // 获取及时回复率
        List<ReplyReportDto> replyReportDtoList = getReplyReportDtos(request, accountRole);
        // 获取chatter在线情况
        final List<UserInfoDto> userInfoDtos = userService.listUserInfos(chatters.parallelStream().map(Chatter::getChatterCode).collect(Collectors.toList()));
        // 获取chatter排班信息
        final List<ChatterWorkingSetDto> chatterWorkingSets = chatterUserService.listChatterWorkingSet(chatters.parallelStream().map(Chatter::getChatterCode).collect(Collectors.toList()));
        // 获取chatter数据
        final List<String> chatterCodes = chatters.parallelStream().map(Chatter::getChatterCode).collect(Collectors.toList());
        final Map<String, RptChatterDataPreDayDto> chatterDataPreDayDtos = qualityService.listChatterData(chatterCodes, toBeginDate(request.getStartDate()), toEndDate(request.getEndDate()));


        return Result.ok(ChatterListRsp.toChatterListRsp(chatters, onlineReportDtoList, replyReportDtoList, userInfoDtos, chatterWorkingSets, chattersCnt, chatterDataPreDayDtos));
    }

    @ApiOperation("model列表接口")
    @RequestMapping(value = "/model/list", method = {RequestMethod.POST})
    public Result<ModelListRsp> modelList(@RequestBody ModelListReq request) {
        if (StringUtils.isEmpty(request.getChatterUserCode())) {
            return Result.fail("chatterUserCode should not be empty");
        }
        if (Objects.isNull(request.getStartDate()) || Objects.isNull(request.getEndDate())) {
            return Result.fail("startDate or endDate should not be empty");
        }
        final List<RptModelDataPreDayDto> modelDataPreDayDtos = qualityService.listModelData(request.getChatterUserCode(), toBeginDate(request.getStartDate()), toEndDate(request.getEndDate()), null);
        if (CollectionUtils.isEmpty(modelDataPreDayDtos)) {
            return Result.ok(ModelListRsp.builder().totalNum(0).build());
        }
        final List<ModelVO> modelList = modelDataPreDayDtos.stream().map(ModelVO::toVo).collect(Collectors.toList());
        return Result.ok(ModelListRsp.builder().totalNum(modelList.size()).modelList(modelList).build());
    }

    @ApiOperation("model会话列表")
    @RequestMapping(value = "/chat/list", method = {RequestMethod.POST})
    public Result<ChatListRsp> chatList(@RequestBody ChatListReq request) {

        if (StringUtils.isEmpty(request.getChatterUserCode())) {
            return Result.fail("chatterUserCode should not be empty");
        }
        if (StringUtils.isEmpty(request.getModelUserCode())) {
            return Result.fail("modelUserCode should not be empty");
        }
        if (request.getPageNum() == null) {
            return Result.fail("pageNum should not be empty");
        }

        // 获取chatter登陆凭证
        final Response<String> toKenRsp = authLoginService.getToKen(request.getChatterUserCode(), UserTokenType.SYSTEM_TOKEN);

        Map<String, String> header = Maps.newHashMap();
        header.put("Content-Type", "application/json");
        header.put("basicParams", "{\"channel\":\"l1\",\"appCode\":\"sparksy\",\"appVersion\":2,\"token\":\""+toKenRsp.getMsg()+"\"}");

        final String response = HttpUtil.postPageBody(chatterApiUrl + "/api/chat/modelChatList", header, JSONObject.toJSONString(request));
        if (StringUtils.isEmpty(response)) {
            return Result.ok();
        }
        final JSONObject responseJson = JSONObject.parseObject(response);
        if (responseJson.getIntValue("code") != 0) {
            log.error("fetchChatListFailed: the response is null, request:{} ", JSONObject.toJSONString(request));
            return Result.fail(responseJson.getString("msg"));
        }

        final String data = responseJson.getString("data");
        if (StringUtils.isEmpty(data)) {
            log.info("fetchChatListFailed: the response data is null, request:{} ", JSONObject.toJSONString(request));
            return Result.ok();
        }

        final ChatListRsp chatListRsp = JSONObject.parseObject(data, ChatListRsp.class);

        if (StringUtils.isNotEmpty(request.getNickName())) {
            final List<ChatAccountVO> conversationChatList = chatListRsp.getConversationChatList();
            if (CollectionUtils.isNotEmpty(conversationChatList)) {
                final List<ChatAccountVO> filterWithNickNameLists = conversationChatList.stream().filter(o -> o.getNickName().equals(request.getNickName())).collect(Collectors.toList());
                chatListRsp.setConversationChatList(filterWithNickNameLists);
            }
        }

        return Result.ok(chatListRsp);
    }


    @ApiOperation("在线用户数")
    @RequestMapping(value = "/chatter/online", method = {RequestMethod.POST})
    public Result<ChatterOnlineRsp> chatterOnline(@RequestBody ChatterOnlineReq request) {
        final List<ChatterOnlineDto> chatterOnlineDtos = qualityService.listChatterOnline(request.getChatterCode(), toBeginDate(request.getStartDate()), toEndDate(request.getEndDate()));
        if (CollectionUtils.isEmpty(chatterOnlineDtos)) {
            return Result.ok(ChatterOnlineRsp.builder().build());
        }
        final List<ChatterOnlineVO> chatterOnlineUsers = chatterOnlineDtos.stream().map(ChatterOnlineVO::toVo).collect(Collectors.toList());
        return Result.ok(ChatterOnlineRsp.builder().chatterList(chatterOnlineUsers).build());
    }

    @ApiOperation("model会话详情")
    @RequestMapping(value = "/chat/detail", method = {RequestMethod.POST})
    public Result<ChatDetailRsp> chatDetail(@RequestBody ChatDetailReq request) {
        if (StringUtils.isEmpty(request.getModelUserCode())) {
            return Result.fail("modelUserCode should not be empty");
        }
        if (StringUtils.isEmpty(request.getUserCode())) {
            return Result.fail("userCode should not be empty");
        }
        if (request.getCurrentPage() == null) {
            return Result.fail("currentPage should not be empty");
        }
        String sessionId = SecureUtil.md5(request.getUserCode() + request.getModelUserCode());
        final UserMsgListDto userMsgListDto = userMsgService.listBySessionId(sessionId, new Page(500, request.getCurrentPage()));
        if (userMsgListDto == null || userMsgListDto.getTotalNum() == 0) {
            return Result.ok();
        }

        final UserBaseDto userAccount = userService.getUserBaseInfoWithoutDeleted(request.getUserCode()).getData();
        final UserBaseDto modelAccount = userService.getUserBaseInfoWithoutDeleted(request.getModelUserCode()).getData();
        final List<UserBenefitsDto> benefits = memberBenefitsService.listBenefits(request.getUserCode(), request.getModelUserCode()).getData();

        final List<MessageDetailVO> messageList = userMsgListDto.getMessageList().stream().map(o -> MessageDetailVO.toVo(o, userAccount, modelAccount, benefits)).collect(Collectors.toList());

        return Result.ok(ChatDetailRsp.builder().totalNum(userMsgListDto.getTotalNum()).messageList(messageList).build());
    }

    @ApiOperation("个人信息展示")
    @RequestMapping(value = "/chat/profile", method = {RequestMethod.POST})
    public Result<UserProfileRsp> profile(@RequestBody ChatProfileVO request) {
        if (StringUtils.isEmpty(request.getChatterUserCode())) {
            return Result.fail("chatterUserCode should not be empty");
        }
        if (StringUtils.isEmpty(request.getUserCode())) {
            return Result.fail("userCode should not be empty");
        }

        // 获取chatter登陆凭证
        final Response<String> toKenRsp = authLoginService.getToKen(request.getChatterUserCode(), UserTokenType.SYSTEM_TOKEN);

        Map<String, String> header = Maps.newHashMap();
        header.put("Content-Type", "application/json");
        header.put("basicParams", "{\"channel\":\"l1\",\"appCode\":\"sparksy\",\"appVersion\":2,\"token\":\""+toKenRsp.getMsg()+"\"}");

        final String response = HttpUtil.postPageBody(chatterApiUrl + "/chatter/userProfile", header, JSONObject.toJSONString(request));
        if (StringUtils.isEmpty(response)) {
            return Result.ok();
        }
        final JSONObject responseJson = JSONObject.parseObject(response);
        if (responseJson.getIntValue("code") != 0) {
            log.error("profile: the response is null, request:{} ", JSONObject.toJSONString(request));
            return Result.fail(responseJson.getString("msg"));
        }

        final String data = responseJson.getString("data");
        if (StringUtils.isEmpty(data)) {
            log.info("profile: the response data is null, request:{} ", JSONObject.toJSONString(request));
            return Result.ok();
        }

        final UserProfileVO userInfoDto = JSONObject.parseObject(data, UserProfileVO.class);
        return Result.ok(UserProfileRsp.toVo(userInfoDto));
    }


    private String setupChatterListQueryParams(@RequestBody ChatterListReq request, BaseCompent.AccountRole accountRole) {
        Map<String, Object> params = Maps.newHashMap();
        if (StringUtils.isNotEmpty(request.getChatterNickName())) {
            params.put("nickName", request.getChatterNickName());
        }
        if (StringUtils.isNotEmpty(request.getChatterAccount())) {
            params.put("account", request.getChatterAccount());
        }
        if (StringUtils.isNotEmpty(request.getModelUserCode())) {
            params.put("modelUserCode", request.getModelUserCode());
        }
        if (StringUtils.isNotEmpty(request.getModelName())) {
            params.put("modelNickName", request.getModelName());
        }
        if (Objects.nonNull(request.getJobType()) && request.getJobType() != 99) {
            params.put("jobType", request.getJobType());
        }
        if (accountRole.getHasViewAllDataPermission()) {

        }
        if (!accountRole.getHasViewAllDataPermission()) {
            params.put("chatterCodes", accountRole.getChatterCodes());
        } else {
            // 当前账号存在查看所有权限数据，如果选择的team非空，则根据所选条件进行查询
            if (CollectionUtils.isNotEmpty(request.getAdminIds())) {
                Boolean hasViewAllDataPermission = Boolean.FALSE;
                List<String> chatterCodes = Lists.newArrayList();
                for(Long adminId : request.getAdminIds()) {
                    final AccountRole accountRoleByAdmin = getAccountRoleByAdminId(adminId);
                    if (accountRoleByAdmin.getHasViewAllDataPermission()) {
                        hasViewAllDataPermission = Boolean.TRUE;
                    } else {
                        chatterCodes.addAll(accountRoleByAdmin.getChatterCodes());
                    }
                }

                if (!hasViewAllDataPermission) {
                    params.put("chatterCodes", chatterCodes);
                }
            }
        }




        return JsonStream.serialize(params);
    }

    private List<OnlineReportDto> getOnlineReportDtos(@RequestBody ChatterListReq request, BaseCompent.AccountRole accountRole) {
        if (!accountRole.getHasViewAllDataPermission()) {
            request.setChatterCodes(accountRole.getChatterCodes());
        }
        final OnlineReportResp onlineReport = reportQueryService.getOnlineTotalReport(getOnlineReportRequest(request), null);
        List<OnlineReportDto> onlineReportDtoList = null;
        if (onlineReport != null) {
            onlineReportDtoList = onlineReport.getOnlineReportDtoList();
        }
        return onlineReportDtoList;
    }


    private OnlineReportRequest getOnlineReportRequest(@RequestBody ChatterListReq request) {
        return OnlineReportRequest.builder().startDate(toBeginDate(request.getStartDate())).endDate(toEndDate(request.getEndDate())).account(request.getChatterAccount()).nickName(request.getChatterNickName()).build();
    }


    private List<ReplyReportDto> getReplyReportDtos(@RequestBody ChatterListReq request, BaseCompent.AccountRole accountRole) {
        if (!accountRole.getHasViewAllDataPermission()) {
            request.setChatterCodes(accountRole.getChatterCodes());
        }
        final ReplyReportResp replyReports = reportQueryService.getReplyReportTotal(getReplyReportRequest(request), null);
        List<ReplyReportDto> replyReportDtoList = null;
        if (replyReports != null) {
            replyReportDtoList = replyReports.getReplyReportDtoList();
        }

        return replyReportDtoList;
    }

    private ReplyReportRequest getReplyReportRequest(@RequestBody ChatterListReq request) {
        return ReplyReportRequest.builder().account(request.getChatterAccount()).nickName(request.getChatterNickName()).startDate(toBeginDate(request.getStartDate())).endDate(toEndDate(request.getEndDate())).build();
    }


}
